from django.http import JsonResponse , HttpResponseForbidden
from django.shortcuts import render
from django.views import View
from haystack.query import SearchQuerySet

from contents.utils import get_category
from goods.models import *
from goods.utils import get_breadcrumb
from goods.models import SKU
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from JiXuShopSystem import settings
from utils.response_code import RETCODE
from datetime import date



# 商品类别
class GoodListView(View):
    def get(self , request , category_id , page):

        # breadcrumb 面包屑功能是实现商品分类界面的
        categories = get_category()
        category = GoodsCategory.objects.get(id=category_id)
        breadcrumb = get_breadcrumb(category)

        # 将商品数据显示在前端中
        sort = request.GET.get('sort' , 'default') # 如果sort不存在则默认为default
        if sort == 'price':
            # 按价格排序
            sort_field = 'price'
        elif sort == 'hot':
            sort_field = 'sales'
        else:
            sort = 'default'
            sort_field = 'create_time'

        skus = SKU.objects.filter(category_id=category_id , is_launched=True).order_by(sort_field)

        # 对商品进行分页
        paginator = Paginator(skus, 20)

        try:
            page_skus = paginator.page(page)
        except PageNotAnInteger:  # 处理用户在 URL 中输入的页数不是整数的情况，将当前页设为第一页
            page_skus = paginator.page(1)
        except EmptyPage:  # 处理用户请求的页面超出搜索结果范围的情况，将当前页设为最后一页。
            page_skus = paginator.page(paginator.num_pages)

        # 获取分页的总数
        total_num = paginator.num_pages



        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'page_skus': page_skus,
            'sort': sort,
            'pag_num': page,
            'category_id': category_id,
            'total_num': total_num
        }

        return render(request, 'list.html', context=context)


# 热销排行
class HotListView(View):
    def get(self , request , category_id):
        skus = SKU.objects.filter(category_id = category_id , is_launched=True).order_by('-sales')[:3]
        hot_skus = []
        for sku in skus:
            sku_dict = {
                'id': sku.id,
                'name': sku.name,
                'price': sku.price,
                'default_image_url': "http://" + sku.default_image.url.replace('http%3A/','')
            }
            hot_skus.append(sku_dict)
        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


# 详情页数据
class DetailView(View):
    '''
    商品详情页
    '''
    def get(self , request , sku_id):
        categories = get_category()
        sku = SKU.objects.get(id=sku_id)
        breadcrumb = get_breadcrumb(sku.category)

        # 通过 sku.id 获取商品对象的对应规格信息的选项
        sku_specs = SKUSpecification.objects.filter(sku_id=sku_id).order_by('spec_id')
        # 创建一个空的列表 用来存储当前 sku 对应的规格选项数据
        sku_key = []
        # 遍历当前 sku 的规格选项
        for spec in sku_specs:
            # 将每个规格选项的 ID 添加到 sku_key 列表中
            sku_key.append(spec.option.id)
        # [8, 11]  颜色：金色 ，内存：64GB
        # [1, 4, 7]  屏幕尺寸：13.3英寸 颜色：银色 ，内存：core i5/8G内存/512G存储

        # 获取当前商品的所有 sku
        # 保证选择不同的规格的情况下 ， 商品不变
        spu_id = sku.spu_id
        spu = SPU.objects.get(id=spu_id)
        skus = SKU.objects.filter(spu_id=spu_id)
        # 构建商品的不同规格参数，sku的选项字段
        spec_sku_map = {}
        for i in skus:
            # 获取sku规格的参数
            s_pecs = i.specs.order_by('spec_id')
            # 创建一个空列表 ， 用于存储 sku 规格参数
            key = []
            # 遍历当前 sku 规格参数列表
            for spec in s_pecs:
                key.append(spec.option.id)
            spec_sku_map[tuple(key)] = i.id

        # 获取当前商品的规格名称
        # 根据商品的 ID 获取当前商品的所有规格名称
        goods_specs = SPUSpecification.objects.filter(spu_id=spu_id).order_by('id')

        # 前端渲染
        # 实现根据规格选项生成对应 sku.id, 更新规格对象个规格选项信息。
        # 为了给用户展示所有的规格参数
        for index , spec in enumerate(goods_specs):
            # 复制 sku_key 列表中的数据，避免直接 sku_key 列表中的内容
            key = sku_key[:]
            # 获取当前 specs 对象的规格名称
            spec_options = spec.options.all()
            # 遍历当前商品的规格名称
            for spec_option in spec_options:
                # 将当前规格选项对象 spec_option 的 id 赋值给 key列表中 index 的位置，用于查询对应 sku 参数内容
                key[index] = spec_option.id
                # 根据列表中的值， 在 spec_sku_map 字典中查询对应的 sku 数据
                spec_option.sku_id = spec_sku_map.get(tuple(key))
            # 更新每个规格对象的选项内容
            spec.spec_options = spec_options

        context = {
            'categories' : categories,
            'breadcrumb' : breadcrumb,
            'sku':sku,
            'specs' : goods_specs,
            'spu' : spu
        }
        return render(request , 'detail.html' , context=context)


# 统计商品类别访问量
class GoodVisitView(View):
    def post(self , request , category_id):
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except Exception:
            return HttpResponseForbidden('商品参数类别不存在')

        # 获取当前日期
        current_date = date.today()


        # 如果你想以特定的格式打印日期，可以使用strftime方法
        formatted_date = current_date.strftime("%Y-%m-%d")


        # 如果数据存在则更新
        try:
            visit_good = GoodsVisitCount.objects.get(category_id=category_id , date=formatted_date)
        except GoodsVisitCount.DoesNotExist:
            visit_good = GoodsVisitCount()

        visit_good.category = category
        visit_good.count += 1
        visit_good.date = formatted_date

        visit_good.save()

        return JsonResponse({'code': RETCODE.OK, 'errmsg': "OK"})



def search_view(request):

    query = request.GET.get('q', '')
    page = request.GET.get('page', 1)
    # 使用 Haystack 的 SearchQuerySet 进行搜索，过滤出包含搜索关键词的结果集
    search_results = SearchQuerySet().filter(content=query)
    paginator = Paginator(search_results, 36)  # 每页显示10条搜索结果

    try:
        results = paginator.page(page)
    except PageNotAnInteger:	# 处理用户在 URL 中输入的页数不是整数的情况，将当前页设为第一页
        results = paginator.page(1)
    except EmptyPage:	# 处理用户请求的页面超出搜索结果范围的情况，将当前页设为最后一页。
        results = paginator.page(paginator.num_pages)
    total_num = paginator.num_pages

    return render(request, 'search.html', {'results': results, 'query': query,'total_num':total_num})









